"""
监听设备上下线
1.只要有一个连接这个socket就
"""
import socketio
from gevent import pywsgi
import redis
import paho.mqtt.client as mqtt
import re

base_topic = "$SYS/brokers/emqx@127.0.0.1/clients/"
offline = "disconnected"
online = "connected"
sio = socketio.Server(async_mode='gevent')
app = socketio.WSGIApp(sio)

redis_client = redis.Redis('localhost', 6379, 0, decode_responses=True)  # 连接redis
client = mqtt.Client()


def on_connect(client, userdata, flags, rc):
    print(f"connect_rc==>{str(rc)}")
    print('mqtt连接成功')


def on_message(client, userdata, msg):
    # 处理信息,将对应的id放到redis里面

    if re.findall('\d+/connected$', msg.topic):
        print("我是mqtt上线")
        client_id = msg.topic.split("/")[-2]
        redis_client.rpush('a', int(client_id))
        new_event()
    elif re.findall('\d+/disconnected$', msg.topic):
        print("我是mqtt下线")
        client_id = msg.topic.split("/")[-2]
        redis_client.lrem('a', 0, int(client_id))
        new_event()
    else:
        print('error')


def on_disconnect(client, userdata, rc):
    print(f"disconnect_rc==>{rc}")
    print("mqtt断开连接")


# @sio.on("emqx")  # 监听这个topic,如果emqx有收取到数据,那么更新数据库,并且从数据库的数据返回给online_offline这个topic中
# def my_event(sid, data):
#     # redis_list = redis_client.lrange('a', 0, -1)
#     # sio.emit('online_offline', data)
#     pass


def new_event():
    redis_list = redis_client.lrange('a', 0, -1)
    sio.emit('online_offline', redis_list)


@sio.event
def connect(sid, environ):
    print('socket connect successful')
    new_event()  # 只要有一个socket连接过来,那么就会从数据库里面获取最新的数据


@sio.event
def disconnect(sid):
    print('socket disconnect successful')


if __name__ == '__main__':
    client.on_connect = on_connect  # mqtt连接之后的回调函数
    client.on_message = on_message  # mqtt接收到数据之后的回调函数
    client.on_disconnect = on_disconnect  # mqtt断开之后的回调函数
    client.connect('47.101.189.16', 1883, 60)  # 连接mqtt服务
    client.subscribe(
        [("$SYS/brokers/emqx@127.0.0.1/clients/+/connected", 0),
         ("$SYS/brokers/emqx@127.0.0.1/clients/+/disconnected", 0)])  # 订阅mqtt的离线和在线信息
    client.loop_start()  # 会处理重新连接,并且会在后台重新开设一个线程,而不会堵塞
    pywsgi.WSGIServer(('0.0.0.0', 5000), app).serve_forever()
